//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<IRenderer.h>
///	@path	~/src/graphics/
///	@date	2007/10/25
///	@desc	Renderer interface.

#pragma once

#include "xeres.h"

#include <vector>

#include "database/store/IFileSystem.h"

#include "graphics/IDevice.h"
#include "graphics/IGeometry.h"
#include "graphics/IDeviceCallback.h"
#include "graphics/IDeviceResource.h"
#include "graphics/IVertexBuffer.h"
#include "graphics/IVertexIndex.h"
#include "graphics/IPass.h"
#include "graphics/IBatch.h"
#include "graphics/ISlotLayout.h"
#include "graphics/IVertexLayout.h"
#include "graphics/IFont.h"
#include "graphics/ISprite.h"
#include "graphics/IEffect.h"
#include "graphics/IEffectPool.h"
#include "graphics/IEffectCompiled.h"
#include "graphics/ITexture.h"
#include "graphics/IRenderTarget.h"
#include "graphics/IRenderTargetSet.h"
#include "graphics/IRenderState.h"
#include "graphics/IBlendState.h"

namespace xeres {

	// forward declaration
	class IFileSystem;
	class RenderManager;
	class RenderContext;

	/*! 
		\enum	ColorOrder
		\brief	Color component order.
				In DirectX 9, color order should be ARGB.
				In DirectX 10, it should be RGBA.
	*/
	enum ColorOrder
	{
		COLOR_ORDER_ARGB	= 0 ,
		COLOR_ORDER_RGBA	= 1 ,
		//
		COLOR_ORDER_last
	};

	/*! 
		\enum	ShaderType
		\brief
	*/
	enum ShaderType
	{
		SHADER_VS	= 1<<1,
		SHADER_PS	= 1<<2,
		SHADER_GS	= 1<<3,
		//
		SHADER_last
	};

	/*!
		\class	IRenderer
		\brief	Abstraction of general renderer.

		\sa IDevice, IResourceManager
	*/
	class IRenderer : public IDeviceCallback
	{
	public:

		/// \name Constructor & Destructor
		//@{

		/// \ctor
		IRenderer( void );

		/// \dtor
		virtual ~IRenderer( void );

		//@}

		DECL_IOBJECT_INTERFACE( IRenderer , IDeviceCallback );

	public:

		/// \name Renderer Initialization, Finalization
		//@{

		/*!
			\brief		Initialize renderer from device.
		*/
		virtual void Initialize( RefWeak<IDevice> device , RefWeak<IData> config ) = 0;

		/*!
			\brief		Finalize renderer.
		*/
		virtual void Finalize( void ) = 0;

		//@}

		/// \brief		Get color order.
		virtual ColorOrder GetColorOrder( void ) const = 0;

		/// \brief		Get device.
		virtual RefWeak<IDevice> GetDevice( void ) = 0;

		/// \name Shading Mode Setup
		//@{

		/*! 
			\brief		Create default shading pass.
		*/
		virtual RefPass<IPass> DefaultShadingPass( void ) = 0;

		//@}

		/// \name Vertex Declaration & Layout
		//@{

		/*!
			\brief		Create vertex layout declaration. Declaration must be sorted by slot and aligned offset.
		*/
		virtual RefPass<IVertexLayout> DeclareVertexLayout( const std::vector<VertexSlotDeclaration>& decl ) = 0;

		/*!
			\brief		Create dynamic vertex from slot.
		*/
		virtual RefPass<IVertexBuffer> CreateDynamicVertex( RefWeak<ISlotLayout> layout , size_t vertex_count , const void * init_data , size_t size ) = 0;

		/*!
			\brief		Create immutable vertex from slot.
		*/
		virtual RefPass<IVertexBuffer> CreateConstantVertex( RefWeak<ISlotLayout> layout , size_t vertex_count , const void * init_data , size_t size ) = 0;

		/*! 
			\brief		Create constant index buffer.
		*/
		virtual RefPass<IVertexIndex> CreateConstantIndex( size_t count , size_t size , const void * init_data ) = 0;

		/*! 
			\brief		Create dynamic index buffer.
		*/
		virtual RefPass<IVertexIndex> CreateDynamicIndex( size_t count , size_t size , const void * init_data ) = 0;

		//@}

		/// \name Geometry Creation
		//@{

		/*!
			\brief		Create simple geometry.
		*/
		virtual RefPass<IGeometry> CreateSimplePolygon(
			TopologyType type ,
			RefWeak<IVertexLayout> layout ,
			size_t vertex_count ,
			const void * vertex_data ,
			size_t index_count ,
			const ushort * index_data
			) = 0;

		/*!
			\brief		Create geometry with vertex declarations.
		*/
		virtual RefPass<IGeometry> CreateGeometry(
			TopologyType type ,
			std::vector< RefWeak<IVertexBuffer> >& vertices ) = 0;

		//@}

		/// \name Resource Management
		//@{

		/*! 
			\brief		Add device resource.
		*/
		virtual void AddDeviceResource( RefWeak<IDeviceResource> res ) = 0;

		/*!
			\brief		Free specific resource from store.
		*/
		virtual void FreeDeviceResource( RefWeak<IDeviceResource> resource ) = 0;

		//@}

		/// \name Sprite Resources
		//@{

		/*!
			\brief		Create font object for render.
		*/
		virtual RefPass<IFont> CreateFont( const WString& faceName ,
			int height , int width , int weight , bool italic , bool highQuality , bool scalable ) = 0;

		/*!
			\brief		Create sprite object for render.
		*/
		virtual RefPass<ISprite> CreateSprite( void ) = 0;

		/*!
			\brief		Create a 2d texture for sprite render.
		*/
		virtual RefPass<ITexture> CreateTextureForSprite( int width , int height ) = 0;

		//@}

		/// \name Render target
		//@{

		/*! 
			\brief		Get default render target.
		*/
		virtual RefWeak<IRenderTarget> GetDefaultRenderTarget( void ) = 0;

		/*! 
			\brief		Get default depth stencil.
		*/
		virtual RefWeak<IRenderTarget> GetDefaultDepthStencil( void ) = 0;

		/*! 
			\brief		Restore default render target.
		*/
		virtual void RestoreDefaultRenderTarget( void ) = 0;

		/*!		
			\brief		Restore default depth stencil.
		*/
		virtual void RestoreDefaultDepthStencil( void ) = 0;

		/*! 
			\brief		Create a custom size color render target. Notice the render target is not lockable (both read & write).
		*/
		virtual RefPass<IRenderTarget> CreateColorRenderTarget( int width , int height ) = 0;

		/*! 
			\brief		Create a render target set to bind render targets.
		*/
		virtual RefPass<IRenderTargetSet> CreateRenderTargetSet( int width , int height ) = 0;

		//@}

		/// \name Effects
		//@{

		/*!
			\brief		Set definition for effect compile.
		*/
		virtual void SetEffectDefinition( const AString& name , const AString& def ) = 0;

		/*!
			\brief		Add include location to compile option.
		*/
		virtual void AddInclude( RefWeak<IFileSystem> filesystem , const WString& path ) = 0;

		/*!
			\brief		Delete include location.
		*/
		virtual void DelInclude( RefWeak<IFileSystem> filesystem , const WString& path ) = 0;

		/*!
			\brief		Create an effect from memory buffer.
		*/
		virtual RefPass<IEffect> CreateEffect( const void * buffer , size_t len , RefWeak<IEffectPool> pool ) = 0;

		/*! 
			\brief		Create an effect pool.
		*/
		virtual RefPass<IEffectPool> CreateEffectPool( const char * buffer , size_t len ) = 0;

		/*! 
			\brief		Get default effect pool.
		*/
		virtual RefWeak<IEffectPool> GetDefaultEffectPool( void ) = 0;

		/*!
			\brief		Compile effect from given source.
		*/
		virtual RefPass<IEffectCompiled> CompileEffect( const char * src , size_t len , RefWeak<IEffectPool> pool ) = 0;

		/*! 
			\brief		Link effect to decl.
		*/
		virtual RefPass<IShaderAdapter> LinkEffect( RefWeak<ITechnique> technique , RefWeak<IVertexLayout> layout ) = 0;

		/*!	
			\brief		Set texture to sampler.
		*/
		virtual bool SetTexture( int shader_type , int sampler , RefWeak<ITexture> texture ) = 0;

		//@}

		/// \name Render States
		//@{

		/*! 
			\brief		Create render state of all.
		*/
		virtual RefPass<IRenderState> CreateStateForAll( void ) = 0;

		/*! 
			\brief		Create blend state.
		*/
		virtual RefPass<IBlendState> CreateBlendState( BlendSet& blend ) = 0;

		/*! 
			\brief		Restore default state.
		*/
		virtual void RestoreDefaultState( void ) = 0;

		//@}
	};

} // namespace xeres
